package com.boarsoft.rpc.demo;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.boarsoft.cache.Cache;
import com.boarsoft.common.Util;
import com.boarsoft.common.util.InetUtil;
import com.boarsoft.rpc.bean.RpcRegistry;
import com.boarsoft.rpc.bean.RpcServiceConfig;
import com.boarsoft.rpc.core.RpcContext;
import com.boarsoft.rpc.listener.RpcListener;
import com.boarsoft.soagov.route.ServiceRouter;

public class DemoRpcHttpRouter implements ServiceRouter<HttpServletRequest>, RpcListener {
	private static final Logger log = LoggerFactory.getLogger(DemoRpcHttpRouter.class);

	@Autowired
	protected RpcContext rpcContext;

	protected Cache cache;

	@Override
	public String getProvider(HttpServletRequest req) {
		// TODO 报文合法性检查
		String service = req.getHeader("service");
		// TODO 是否泛化调用
		boolean gen = true;
		// TODO 从HTTP请求取出用于决定路由的键值
		String pod = this.getPod(req);
		//
		RpcContext.specify2(pod);
		try {
			String addr = rpcContext.getProvider(service, gen, null, null, null);
			if (Util.strIsEmpty(addr)) {
				log.warn("Can not find provider of service {}/{}", service, pod);
			}
			return addr;
		} finally {
			RpcContext.specify2(null);
		}
	}

	public String getPod(HttpServletRequest req) {
		// TODO 根据要素获取或生成缓存键
		String key = "010100000001";
		// 到缓存查询POD
		String pod = cache.str("route", key);
		// 未命中则计算或查询POD
		if (Util.strIsEmpty(pod)) {
			// TODO 根据要素计算或到数据库查询POD
			pod = "2";
			// TODO 这里暂不考虑大并发
			cache.str("route", key, pod, 86400);
		}
		return pod;
	}

	public RpcContext getRpcContext() {
		return rpcContext;
	}

	public void setRpcContext(RpcContext rpcContext) {
		this.rpcContext = rpcContext;
	}

	public Cache getCache() {
		return cache;
	}

	public void setCache(Cache cache) {
		this.cache = cache;
	}

	@Override
	public void onRemoveLink(String addr, String reason) {
		// Nothing to do
	}

	@Override
	public void onRegister(RpcRegistry reg) {
		// Nothing to do
	}

	@Override
	public void onDeregister(RpcRegistry reg) {
		// Nothing to do
	}

	@Override
	public void onUpdateRegistry(RpcRegistry rr) {
		String addr = rr.getKey();
		// 不检查自己的注册表
		if (InetUtil.getAddr().equals(addr)) {
			return;
		}
		// 来自远程的serviceMap
		Map<String, RpcServiceConfig> sm = rr.getServiceMap();
		for (String sk : sm.keySet()) {
			log.debug("Found service provider {} -> {}", addr, sk);
			RpcServiceConfig sc = sm.get(sk);
			// 如果服务状态为不可用，则将远程节点放到禁用的服务提供者列表
			if (sc.isEnable()) {
				this.rpcContext.putProvider(rr, addr);
			} else {
				this.rpcContext.putProvider2(rr, addr);
			}
		}
	}

	@Override
	public void config() {
		// TODO Auto-generated method stub
		
	}
}
